[IA64] Fix shadow_op hypercall
authorAlex Williamson <alex.williamson@hp.com>
Wed, 6 Feb 2008 18:23:16 +0000 (11:23 -0700)
committerAlex Williamson <alex.williamson@hp.com>
Wed, 6 Feb 2008 18:23:16 +0000 (11:23 -0700)
Fix SHADOW_OP_ENABLE_LOGDIRTY and SHADOW_OP_CLEAN hypercall.

Live migation doesn't work because the VHPT is not flushed.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>
xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/vhpt.c
xen/include/asm-ia64/tlbflush.h

index 17375693dd85c27bfdc8a8fed3423f26fea39ccc..ffca9533c57a84f5c53e1b14a747def11f8a0a8a 100644 (file)
@@ -1785,7 +1785,7 @@ int shadow_mode_control(struct domain *d, xen_domctl_shadow_op_t *sc)
                                v->arch.shadow_bitmap = d->arch.shadow_bitmap;
                        /* Flush vhtp and tlb to enable dirty bit
                           virtualization.  */
-                       domain_flush_tlb_vhpt(d);
+                       flush_tlb_for_log_dirty(d);
                }
                break;
 
@@ -1824,6 +1824,7 @@ int shadow_mode_control(struct domain *d, xen_domctl_shadow_op_t *sc)
 
                        memset((uint8_t *)d->arch.shadow_bitmap + i, 0, size);
                }
+               flush_tlb_for_log_dirty(d);
                
                break;
          }
index e5aac9aa435cc4994a2e216a9bb7a1352f1fcf9b..19d91f5505592c46e9511ff8b96af3da3f4e9e6b 100644 (file)
@@ -521,6 +521,31 @@ void domain_flush_tlb_vhpt(struct domain *d)
        cpus_clear (d->domain_dirty_cpumask);
 }
 
+void flush_tlb_for_log_dirty(struct domain *d)
+{
+       struct vcpu *v;
+
+       /* NB. There is no race because all vcpus are paused. */
+       if (is_hvm_domain(d)) {
+               for_each_vcpu (d, v) {
+                       /* XXX: local_flush_tlb_all is called redundantly */
+                       thash_purge_all(v);
+               }
+               smp_call_function((void (*)(void *))local_flush_tlb_all, 
+                                       NULL, 1, 1);
+       } else if (HAS_PERVCPU_VHPT(d)) {
+               for_each_vcpu (d, v) {
+                       vcpu_purge_tr_entry(&PSCBX(v,dtlb));
+                       vcpu_purge_tr_entry(&PSCBX(v,itlb));
+                       vcpu_vhpt_flush(v);
+               }
+               on_each_cpu((void (*)(void *))local_flush_tlb_all, NULL, 1, 1);
+       } else {
+               on_each_cpu((void (*)(void *))flush_tlb_vhpt_all, d, 1, 1);
+       }
+       cpus_clear (d->domain_dirty_cpumask);
+}
+
 void flush_tlb_mask(cpumask_t mask)
 {
     int cpu;
index a659f6a0e417d52935159ccb4908dd0312209aaa..00b72235e03b66fff38c7201796608f236283065 100644 (file)
@@ -34,6 +34,9 @@ void domain_flush_vtlb_track_entry(struct domain* d,
 /* Flush vhpt and mTLB on every dirty cpus.  */
 void domain_flush_tlb_vhpt(struct domain *d);
 
+/* Flush vhpt and mTLB for log-dirty mode.  */
+void flush_tlb_for_log_dirty(struct domain *d);
+
 /* Flush v-tlb on cpus set in mask for current domain.  */
 void flush_tlb_mask(cpumask_t mask);